<?php
/***************************************************************
*  Copyright notice
*  (c) 2009, jianyuzhu@gmail.com
*  All rights reserved
*  This script is part of the PPEMI project.
***************************************************************/

class CoreCrypt {
	var $type = 'base64';
	var $ekey = '$PPEMI$';
	
	//constructor
	function CoreCrypt() {
		//
	}
	
	//methods
	function encrypt($data, $key = '') {
		$r = '';
		if( $key == '' ) {
			$key = $this->_key();
		}
		switch($this->type) {
			case 'base64':
				$r = $this->_base64_encode($data);
				break;
			case 'base64key':
				$r = $this->_base64_encode_a($data, $key);
				break;
			case 'mcrypt':
				$r = $this->_mcrypt_encrypt($data, $key);
				break;
			case 'md5':
				$r = $this->_md5_encrypt($data, $key);
				break;
			case 'md5t':
				$r = $this->_md5_encrypt_t($data, $key);
				break;
			case 'md5b':
				$r = $this->_md5_encrypt_b($data, $key);
				break;
			default:
				
				break;
		}
		
		return $r;
	}
	
	function decrypt($data, $key = '') {
		$r = '';
		if( $key == '' ) {
			$key = $this->_key();
		}
		switch($this->type) {
			case 'base64':
				$r = $this->_base64_decode($data);
				break;
			case 'base64key':
				$r = $this->_base64_decode_a($data, $key);
				break;
			case 'mcrypt':
				$r = $this->_mcrypt_decrypt($data, $key);
				break;
			case 'md5':
				$r = $this->_md5_decrypt($data, $key);
				break;
			case 'md5t':
				$r = $this->_md5_decrypt_t($data, $key);
				break;
			case 'md5b':
				$r = $this->_md5_decrypt_b($data, $key);
				break;
			default:
				break;
		}
		
		return $r;
	}
	
	//
	function _key() {
		if( strlen($this->ekey) == 0 ) {
			$this->ekey = '$PPEMI$';
		}
		
		return $this->ekey;
	}
	
	//base64
	function _base64_encode($data) {
		return base64_encode($data);
	}
	
	function _base64_decode($data) {
		return base64_decode($data);
	}
	
	//base64 key
	function _base64_encode_a($data, $key) {
		$r = '';
		$k = strlen($key);
		for($i=0, $n=strlen($data); $i<$n; $i++) {
			$c = substr($data, $i, 1);
			$b = substr($key, ($i % $k) - 1, 1);
			$c = chr(ord($c) + ord($b));
			$r .= $c;
		}
		
		return base64_encode($r);
	}
	
	function _base64_decode_a($data, $key) {
		$r = '';
		$data = base64_decode($data);
		$k = strlen($key);
		for($i=0, $n=strlen($data); $i<$n; $i++) {
			$c = substr($data, $i, 1);
			$b = substr($key, ($i % $k) - 1, 1);
			$c = chr(ord($c) - ord($b));
			$r .= $c;
		}
		
		return $r;
	}
	
	//mcrypt
	function _mcrypt_encrypt($data, $key) {
		$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
		$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
		
		$crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $data, MCRYPT_MODE_ECB, $iv);
		
		return $crypttext;
	}
	
	function _mcrypt_decrypt($data, $key) {
		$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
		$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
		
		$crypttext = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $data, MCRYPT_MODE_ECB, $iv);
		
		return $crypttext;
	}
	
	//md5
	function _md5_ed($data, $key) {
		if( $key == '' ) {
			$key = $this->_key();
		}
		$a = md5($key);
		$b = strlen($a);
		$r = '';
		$c = 0;
		for($i=0, $n=strlen($data); $i<$n; $i++) {
			if( $c == $b ) {
				$c = 0;
			}
			$r .= substr($data, $i, 1) ^ substr($a, $c, 1);
			$c++;
		}
		
		return $r;
	}
	
	function _md5_encrypt($data, $key) {
		srand((double)microtime()*1000000);
		$a = md5(rand(0, 32000));
		$b = strlen($key);
		$c = 0;
		$r = '';
		for($i=0, $n=strlen($data); $i<$n; $i++) {
			if( $c == $b ) {
				$c = 0;
			}
			$r .= substr($a, $c, 1) . (substr($data, $i, 1) ^ substr($a, $c, 1));
			$c++;
		}
		
		return $this->_md5_ed($r, $key);
	}
	
	function _md5_decrypt($data, $key) {
		$data = $this->_md5_ed($data, $key);
		$r = '';
		for($i=0, $n=strlen($data); $i<$n; $i++) {
			$b = substr($data, $i, 1);
			$i++;
			$r .= substr($data, $i, 1) ^ $b;
		}
		
		return $r;
	}
	
	//
	function _md5_encrypt_t($data, $key) {
		$data = $this->_md5_encrypt($data, $key);
		$data = implode('', unpack("H*", $data));
		
		return $data;
	}
	
	function _md5_decrypt_t($data, $key) {
		$data = pack("H*", $data);
		$data = $this->_md5_decrypt($data, $key);
		
		return $data;
	}
	
	//
	function _md5_encrypt_b($data, $key) {
		$data = $this->_md5_encrypt($data, $key);
		
		include_once(CONFIG_PATH . CONFIG_DIR_CLASSES . 'core.crypt.uri.class.php');
		$euObj = new CoreCryptURI();
		$data = $euObj->encode($data);
		
		return $data;
	}
	
	function _md5_decrypt_b($data, $key) {
		include_once(CONFIG_PATH . CONFIG_DIR_CLASSES . 'core.crypt.uri.class.php');
		$euObj = new CoreCryptURI();
		$data = $euObj->encode($data);
		
		$data = $this->_md5_encrypt($data, $key);
		
		return $data;
	}
}
//
?>